// 468. 验证IP地址



/**
 * 正则
 * 一部分一部分判断
 */

function validIPAddress(IP: string): string {
    const IPv4 = 'IPv4'
    const IPv6 = 'IPv6'
    const Neither = 'Neither'

    const ipv4 = /^0$|^[1-9]\d{0,2}$/
    const ipv6 = /^[a-f0-9A-F]{1,4}$/
    if(IP.indexOf('.')!=-1){
        const items = IP.split('.')
        return items.length==4&&items.every(i=>i.match(ipv4)&&Number.parseInt(i)<=255)? IPv4: Neither
    }else if(IP.indexOf(':')!=-1){
        const items = IP.split(':')
        //? 感觉有问题，这个题好像默认了不能::
        return items.length==8&&items.every(i=>i.match(ipv6))? IPv6: Neither
    }
    return Neither
};


/**
 * 面向测试用例编程
 */
function numOfIPv4(s:string):boolean{
    if(s.length>3||s.length==0) return false
    if(s.length!=1&&s[0]=='0') return false
    if(s==='00'||s=='000') return false

    const zero = '0'.charCodeAt(0)
    const nine = '9'.charCodeAt(0)
    let ans = 0
    let pow = 1
    for(let it of Array.from(s).reverse()){
        const cc = it.charCodeAt(0)
        if(cc<zero||cc>nine) return false
        ans += pow*(cc-zero)
        pow*=10
    }
    if(ans>255) return false
    return true
}

function numOfIPv6(s:string):boolean{
    if(s.length>4||s.length==0) return false
    const zero = '0'.charCodeAt(0)
    const nine = '9'.charCodeAt(0)
    const a = 'a'.charCodeAt(0)
    const f = 'f'.charCodeAt(0)
    for(let c of Array.from(s)){
        const cc = c.toLowerCase().charCodeAt(0)
        if(!(cc>=zero&&cc<=nine)&&!(cc>=a&&cc<=f)) return false
    }
    return true
}

function validIPAddress_five(IP: string): string {
    const ipv4 = 'IPv4'
    const ipv6 = 'IPv6'
    const neither = 'Neither'
    if(IP.indexOf('.')!=-1){
        const n = IP.split('.')
        if(n.length!=4) return neither
        for(let i=0;i<4;i++){
            const it = n[i]
            if(!numOfIPv4(it)) return neither
        }
        return ipv4
    }else if(IP.indexOf(':')!=-1){
        const n = IP.split('::')
        if(n.length>2) return neither
        let items = n[0].split(':')
        if(n.length==2){
            items = items.concat(n[1].split(':'))
            if(items.length>=7) return neither
        }
        if(items.length>8) return neither
        for(let five of items){
            if(!numOfIPv6(five)) return neither
        }
        return ipv6
    }
    return neither
};


